import json
import time

from channels.generic.websocket import WebsocketConsumer
from asgiref.sync import async_to_sync
from django.contrib.auth import get_user_model
from django.forms import model_to_dict
from rest_framework_simplejwt.authentication import JWTAuthentication

from chat_api.models import *


class ChatConsumer(WebsocketConsumer, JWTAuthentication):

    def connect(self):
        # async_to_sync(self.channel_layer.group_add)('x1', self.channel_name)
        self.accept()
        self.user_model = get_user_model()
        try:
            token = str(self.scope['query_string'].decode('utf-8')).replace("token=", "")
            validated_token = self.get_validated_token(token)
            self.scope['user'] = JWTAuthentication.get_user(self, validated_token=validated_token)
            user_id = self.scope['user'].id
            client = Client.objects.get_or_create(user_id=user_id)[0]
            client.channel_name = self.channel_name
            client.save()

            notes = Note.objects.filter(to_id=user_id)
            for i in notes:
                self.send(json.dumps({"time": i.time, "msg": i.msg, "from": i.from_name,
                           "from_id": i.from_id}))
            notes.delete()
        except Exception as e:
            self.send(text_data=json.dumps(e.__dict__['detail']['messages'][0]))
            self.close()

    def receive(self, text_data=None, bytes_data=None):
        # 格式化数据
        get = json.loads(text_data)
        from_person = self.scope['user'].id  # 谁发过来
        to_person = get['to']  # 发给谁
        msg = get['msg']  # 发送的文本
        time = get['time']  # 发送的文本
        name = User.objects.get(id=from_person).first_name
        try:
            channel_name = Client.objects.get(user_id=to_person).channel_name
            # 单独发
            async_to_sync(self.channel_layer.send)(Client.objects.get(user_id=to_person).channel_name, {
                'type': 'chat.send',
                'message': {"time": time, "msg": msg, "from": name,
                            "from_id": from_person}
            })
        except:
            # 不在线,保存记录
            Note.objects.create(time=time, msg=msg, from_name=name, from_id=from_person, to_id=to_person)

    def chat_send(self, event):
        message = event['message']
        self.send(json.dumps(message))

    def disconnect(self, code):
        Client.objects.filter(channel_name=self.channel_name).delete()
